package com.zwh.gateway.zuul.custom;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.BasicHttpEntity;
import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpRequest;
import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext;

import java.util.List;
import java.util.Map;

import static org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer.Runner.customize;

/**
 * @author zwh
 * @date 2023-4-3
 */
public class CustomRibbonApacheHttpRequest extends RibbonApacheHttpRequest {
    private GatewayServiceTimeoutProperties gatewayServiceTimeoutProperties;

    public CustomRibbonApacheHttpRequest(RibbonCommandContext context) {
        super(context);
    }

    @Override
    public HttpUriRequest toRequest(final RequestConfig requestConfig) {
        // 先执行RibbonApacheHttpRequest.toRequest()，获取到build为止，在进行自定义逻辑
        RequestBuilder builder = toRequestSuper();
        RequestConfig customRequestConfig = requestConfig;
        // 自定义配置不为空时，设置为自定义配置
        if (!this.gatewayServiceTimeoutProperties.getServiceIdConfig().isEmpty()) {
            for (Map.Entry<String, GatewayServiceTimeoutProperties.Config> serviceIdConfigItem
                    : this.gatewayServiceTimeoutProperties.getServiceIdConfig().entrySet()) {
                if (this.getContext().getServiceId().equals(serviceIdConfigItem.getKey())) {
                    RequestConfig.Builder configBuilder = RequestConfig.copy(requestConfig);
                    configBuilder.setConnectTimeout(serviceIdConfigItem.getValue().getConnectTimeout());
                    configBuilder.setSocketTimeout(serviceIdConfigItem.getValue().getReadTimeout());
                    customRequestConfig = configBuilder.build();
                }
            }
        }
        builder.setConfig(customRequestConfig);
        return builder.build();
    }

    /**
     * 复制父类的toRequest代码 RibbonApacheHttpRequest.toRequest()
     * @return
     */
    public RequestBuilder toRequestSuper(){
        final RequestBuilder builder = RequestBuilder.create(this.context.getMethod());
        builder.setUri(this.uri);
        for (final String name : this.context.getHeaders().keySet()) {
            final List<String> values = this.context.getHeaders().get(name);
            for (final String value : values) {
                builder.addHeader(name, value);
            }
        }

        for (final String name : this.context.getParams().keySet()) {
            final List<String> values = this.context.getParams().get(name);
            for (final String value : values) {
                builder.addParameter(name, value);
            }
        }

        if (this.context.getRequestEntity() != null) {
            final BasicHttpEntity entity;
            entity = new BasicHttpEntity();
            entity.setContent(this.context.getRequestEntity());
            // if the entity contentLength isn't set, transfer-encoding will be set
            // to chunked in org.apache.http.protocol.RequestContent. See gh-1042
            Long contentLength = this.context.getContentLength();
            if ("GET".equals(this.context.getMethod())
                    && (contentLength == null || contentLength < 0)) {
                entity.setContentLength(0);
            }
            else if (contentLength != null) {
                entity.setContentLength(contentLength);
            }
            builder.setEntity(entity);
        }

        customize(this.context.getRequestCustomizers(), builder);
        return builder;
    }


    public void setGatewayServiceTimeoutProperties(GatewayServiceTimeoutProperties gatewayServiceTimeoutProperties) {
        this.gatewayServiceTimeoutProperties = gatewayServiceTimeoutProperties;
    }
}
